home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / etc / apparmor / rc.apparmor.functions < prev    next >
Text File  |  2008-10-08  |  13KB  |  508 lines

  1. #!/bin/sh
  2. #
  3. #    $Id: rc.apparmor.functions 1280 2008-06-09 11:00:28Z jrjohansen $
  4. #
  5. # ----------------------------------------------------------------------
  6. #    Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
  7. #    NOVELL (All rights reserved)
  8. #
  9. #    This program is free software; you can redistribute it and/or
  10. #    modify it under the terms of version 2 of the GNU General Public
  11. #    License published by the Free Software Foundation.
  12. #
  13. #    This program is distributed in the hope that it will be useful,
  14. #    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. #    GNU General Public License for more details.
  17. #
  18. #    You should have received a copy of the GNU General Public License
  19. #    along with this program; if not, contact Novell, Inc.
  20. # ----------------------------------------------------------------------
  21. # rc.apparmor.functions by Steve Beattie
  22. #
  23. # NOTE: rc.apparmor initscripts that source this file need to implement
  24. # the following set of functions:
  25. #    aa_action
  26. #    aa_log_success_msg
  27. #    aa_log_warning_msg
  28. #    aa_log_failure_msg
  29. #    aa_log_skipped_msg
  30.  
  31. # Some nice defines that we use
  32.  
  33. CONFIG_DIR=/etc/apparmor
  34. MODULE=apparmor
  35. OLD_MODULE=subdomain
  36. if [ -f "${CONFIG_DIR}/${MODULE}.conf" ] ; then
  37.     APPARMOR_CONF="${CONFIG_DIR}/${MODULE}.conf"
  38. elif [ -f "${CONFIG_DIR}/${OLD_MODULE}.conf" ] ; then
  39.     APPARMOR_CONF="${CONFIG_DIR}/${OLD_MODULE}.conf"
  40. elif [ -f "/etc/immunix/subdomain.conf" ] ; then
  41.     aa_log_warning_msg "/etc/immunix/subdomain.conf is deprecated, use ${CONFIG_DIR}/subdomain.conf instead"
  42.     APPARMOR_CONF="/etc/immunix/subdomain.conf"
  43. elif [ -f "/etc/subdomain.conf" ] ; then
  44.     aa_log_warning_msg "/etc/subdomain.conf is deprecated, use ${CONFIG_DIR}/subdomain.conf instead"
  45.     APPARMOR_CONF="/etc/subdomain.conf"
  46. else
  47.     aa_log_warning_msg "Unable to find config file in ${CONFIG_DIR}, installation problem?"
  48. fi
  49.  
  50. # Read configuration options from /etc/subdomain.conf, default is to
  51. # warn if subdomain won't load.
  52. SUBDOMAIN_MODULE_PANIC="warn"
  53. SUBDOMAIN_ENABLE_OWLSM="no"
  54. APPARMOR_ENABLE_AAEVENTD="no"
  55.  
  56. if [ -f "${APPARMOR_CONF}" ] ; then
  57.     #parse the conf file to see what we should do
  58.     . "${APPARMOR_CONF}"
  59. fi
  60.  
  61. PARSER=/sbin/apparmor_parser
  62.  
  63. # SUBDOMAIN_DIR and APPARMOR_DIR might be defined in subdomain.conf|apparmor.conf
  64. if [ -d "${APPARMOR_DIR}" ] ; then
  65.     PROFILE_DIR=${APPARMOR_DIR}
  66. elif [ -d "${SUBDOMAIN_DIR}" ] ; then
  67.     PROFILE_DIR=${SUBDOMAIN_DIR}
  68. elif [ -d /etc/apparmor.d ] ; then
  69.     PROFILE_DIR=/etc/apparmor.d
  70. elif [ -d /etc/subdomain.d ] ; then
  71.     PROFILE_DIR=/etc/subdomain.d
  72. fi
  73. ABSTRACTIONS="-I${PROFILE_DIR}"
  74. AA_EV_BIN=/usr/sbin/aa-eventd
  75. AA_EV_PIDFILE=/var/run/aa-eventd.pid
  76. AA_STATUS=/usr/sbin/apparmor_status
  77. SD_EV_BIN=/usr/sbin/sd-event-dispatch.pl
  78. SD_EV_PIDFILE=/var/run/sd-event-dispatch.init.pid
  79. SD_STATUS=/usr/sbin/subdomain_status
  80. SECURITYFS=/sys/kernel/security
  81.  
  82. SUBDOMAINFS_MOUNTPOINT=$(grep subdomainfs /etc/fstab  | \
  83.     sed -e 's|^[[:space:]]*[^[:space:]]\+[[:space:]]\+\(/[^[:space:]]*\)[[:space:]]\+subdomainfs.*$|\1|' 2> /dev/null)
  84.  
  85. if [ -d "/var/lib/${MODULE}" ] ; then
  86.     APPARMOR_TMPDIR="/var/lib/${MODULE}"
  87. elif [ -d "/var/lib/${OLD_MODULE}" ] ; then
  88.     APPARMOR_TMPDIR="/var/lib/${OLD_MODULE}"
  89. else
  90.     APPARMOR_TMPDIR="/tmp"
  91. fi
  92.  
  93.  
  94. # keep exit status from parser during profile load.  0 is good, 1 is bad
  95. STATUS=0
  96.  
  97. # Test if the apparmor "module" is present.
  98. is_apparmor_present() {
  99.     local modules=$1
  100.     shift
  101.  
  102.     while [ $# -gt 0 ] ; do
  103.         modules="$modules|$1"
  104.         shift
  105.     done
  106.  
  107.     # check for subdomainfs version of module
  108.     grep -qE "^($modules)[[:space:]]" /proc/modules
  109.     
  110.     if [ $? -ne 0 ] ; then
  111.         ls /sys/module/apparmor 2>/dev/null | grep -qE "^($modules)" 
  112.     fi
  113.  
  114.     return $?
  115. }
  116.  
  117. # This set of patterns to skip needs to be kept in sync with
  118. # SubDomain.pm::isSkippableFile()
  119. skip_profile() {
  120.     local profile=$1
  121.     if [ "${profile%.rpmnew}" != "${profile}" -o \
  122.          "${profile%.rpmsave}" != "${profile}" -o \
  123.          "${profile%.dpkg-new}" != "${profile}" -o \
  124.          "${profile%.dpkg-old}" != "${profile}" -o \
  125.          "${profile%.dpkg-dist}" != "${profile}" -o \
  126.          -e "${PROFILE_DIR}/disable/`basename ${profile}`" -o \
  127.          "${profile%\~}" != "${profile}" ] ; then
  128.         return 0
  129.     fi
  130.  
  131.     return 1
  132. }
  133.  
  134. force_complain() {
  135.     local profile=$1
  136.  
  137.     # if profile not in complain mode
  138.     if ! egrep -q "^/.*[ \t]+flags[ \t]*=[ \t]*\([ \t]*complain[ \t]*\)[ \t]+{" $profile ; then
  139.         local link="${PROFILE_DIR}/force-complain/`basename ${profile}`"
  140.         if [ -e "$link" ] ; then
  141.             echo "Warning: found $link, forcing complain mode"
  142.             return 0
  143.         fi
  144.     fi
  145.  
  146.     return 1
  147. }
  148.  
  149. parse_profiles() {
  150.     # get parser arg
  151.     case "$1" in
  152.         load)
  153.             PARSER_ARGS="--add"
  154.             PARSER_MSG="Loading AppArmor profiles "
  155.             ;;
  156.         reload)
  157.             PARSER_ARGS="--replace"
  158.             PARSER_MSG="Reloading AppArmor profiles "
  159.             ;;
  160.         *)
  161.             exit 1
  162.             ;;
  163.     esac
  164.     echo -n "$PARSER_MSG"
  165.     # run the parser on all of the apparmor profiles
  166.     if [ ! -f "$PARSER" ]; then
  167.         aa_log_failure_msg "- AppArmor parser not found"
  168.         exit 1
  169.     fi
  170.  
  171.     if [ ! -d "$PROFILE_DIR" ]; then
  172.         aa_log_skipped_msg "- Profile directory not found\nNo AppArmor policy loaded."
  173.         return 1
  174.     fi
  175.  
  176.     if [ -z "$(ls $PROFILE_DIR/)" ]; then
  177.         aa_log_skipped_msg "- No profiles found\nNo AppArmor policy loaded."
  178.         return 1
  179.     fi
  180.  
  181.     for profile in $PROFILE_DIR/*; do
  182.         if skip_profile "${profile}" ; then
  183.             echo " Skipping profile $profile"
  184.             logger -t "AppArmor(init)" -p daemon.warn "Skipping profile $profile"
  185.             STATUS=2
  186.         elif [ -f "${profile}" ] ; then
  187.             COMPLAIN=""
  188.             if force_complain "${profile}" ; then
  189.                 COMPLAIN="-C"
  190.             fi
  191.             $PARSER $ABSTRACTIONS $PARSER_ARGS $COMPLAIN "$profile" > /dev/null
  192.             if [ $? -ne 0 ]; then
  193.                 echo " Profile $profile failed to load"
  194.                 STATUS=1
  195.             fi
  196.         fi
  197.     done
  198.     if [ $STATUS -eq 0 ]; then
  199.         aa_log_success_msg
  200.     elif [ $STATUS -eq 2 ]; then
  201.         aa_log_warning_msg
  202.     else
  203.         aa_log_failure_msg
  204.         exit $STATUS
  205.     fi
  206. }
  207.  
  208. profiles_names_list() {
  209.     # run the parser on all of the apparmor profiles
  210.     TMPFILE=$1
  211.     if [ ! -f "$PARSER" ]; then
  212.         aa_log_failure_msg "- AppArmor parser not found"
  213.         exit 1
  214.     fi
  215.  
  216.     if [ ! -d "$PROFILE_DIR" ]; then
  217.         aa_log_failure_msg "- Profile directory not found"
  218.         exit 1
  219.     fi
  220.  
  221.     for profile in $PROFILE_DIR/*; do
  222.             if ! skip_profile "${profile}" && [ -f "${profile}" ] ; then
  223.             LIST_ADD=$($PARSER $ABSTRACTIONS -N "$profile" | grep -v '\^')
  224.             if [ $? -eq 0 ]; then
  225.                 echo "$LIST_ADD" >>$TMPFILE
  226.             fi
  227.         fi
  228.     done
  229. }
  230.  
  231. failstop_system() {
  232.     level=$(runlevel | cut -d" " -f2)
  233.     if [ $level -ne "1" ] ; then
  234.         aa_log_failure_msg "- could not start AppArmor.  Changing to runlevel 1"
  235.         telinit 1;
  236.         return -1;
  237.     fi
  238.     aa_log_failure_msg "- could not start AppArmor."
  239.     return -1
  240. }
  241.  
  242. module_panic() {
  243.     # the module failed to load, determine what action should be taken
  244.  
  245.     case "$SUBDOMAIN_MODULE_PANIC" in
  246.         "warn"|"WARN")
  247.             return 1 ;;
  248.         "panic"|"PANIC") failstop_system
  249.             rc=$?
  250.             return $rc ;;
  251.         *) aa_log_failure_msg "- invalid AppArmor module fail option"
  252.             return -1 ;;
  253.     esac
  254. }
  255.  
  256. is_apparmor_loaded() {
  257.     if ! is_securityfs_mounted ; then
  258.         mount_securityfs
  259.     fi
  260.  
  261.     mount_subdomainfs
  262.  
  263.     if [ -f "${SECURITYFS}/${MODULE}/profiles" ]; then
  264.         SFS_MOUNTPOINT="${SECURITYFS}/${MODULE}"
  265.         return 0
  266.     fi
  267.  
  268.     if [ -f "${SECURITYFS}/${OLD_MODULE}/profiles" ]; then
  269.         SFS_MOUNTPOINT="${SECURITYFS}/${OLD_MODULE}"
  270.         return 0
  271.     fi
  272.  
  273.     if [ -f "${SUBDOMAINFS_MOUNTPOINT}/profiles" ]; then
  274.         SFS_MOUNTPOINT=${SUBDOMAINFS_MOUNTPOINT}
  275.         return 0
  276.     fi
  277.  
  278.     # check for subdomainfs version of module
  279.     is_apparmor_present apparmor subdomain
  280.  
  281.     return $?
  282. }
  283.  
  284. is_securityfs_mounted() {
  285.     grep -q securityfs /proc/filesystems && grep -q securityfs /proc/mounts
  286.     return $?
  287. }
  288.  
  289. mount_securityfs() {
  290.     if grep -q securityfs /proc/filesystems ; then
  291.         aa_action "Mounting securityfs on ${SECURITYFS}" \
  292.                 mount -t securityfs securityfs "${SECURITYFS}"
  293.         return $?
  294.     fi
  295.     return 0
  296. }
  297.  
  298.  
  299. mount_subdomainfs() {
  300.     # for backwords compatibility
  301.     if grep -q subdomainfs /proc/filesystems && \
  302.        ! grep -q subdomainfs /proc/mounts && \
  303.        [ -n "${SUBDOMAINFS_MOUNTPOINT}" ]; then
  304.         aa_action "Mounting subdomainfs on ${SUBDOMAINFS_MOUNTPOINT}" \
  305.                 mount "${SUBDOMAINFS_MOUNTPOINT}"
  306.         return $?
  307.     fi
  308.     return 0
  309. }
  310.  
  311. unmount_subdomainfs() {
  312.     SUBDOMAINFS=$(grep subdomainfs /proc/mounts  | cut -d" " -f2 2> /dev/null)
  313.     if [ -n "${SUBDOMAINFS}" ]; then
  314.         aa_action "Unmounting subdomainfs" umount ${SUBDOMAINFS}
  315.     fi
  316. }
  317.  
  318. load_module() {
  319.     local rc=0
  320.     if modinfo -F filename apparmor > /dev/null 2>&1 ; then
  321.         MODULE=apparmor
  322.     elif modinfo -F filename ${OLD_MODULE} > /dev/null 2>&1 ; then
  323.         MODULE=${OLD_MODULE}
  324.     fi
  325.  
  326.     if ! is_apparmor_present apparmor subdomain ; then
  327.         aa_action "Loading AppArmor module" /sbin/modprobe -q $MODULE $1
  328.         rc=$?
  329.         if [ $rc -ne 0 ] ; then
  330.             module_panic
  331.             rc=$?
  332.             if [ $rc -ne 0 ] ; then
  333.                 exit $rc
  334.             fi
  335.         fi
  336.     fi
  337.  
  338.     if ! is_apparmor_loaded ; then
  339.         return 1
  340.     fi
  341.  
  342.     return $rc
  343. }    
  344.  
  345. apparmor_start() {
  346.     if ! is_apparmor_loaded ; then
  347.         load_module
  348.         rc=$?
  349.         if [ $rc -ne 0 ] ; then
  350.             return $rc
  351.         fi
  352.     fi
  353.  
  354.     if [ ! -w "$SFS_MOUNTPOINT/.load" ] ; then
  355.         aa_log_failure_msg "Loading AppArmor profiles - failed, Do you have the correct privileges?"
  356.         return 1
  357.     fi
  358.  
  359.     configure_owlsm
  360.  
  361.     if [ $(wc -l "$SFS_MOUNTPOINT/profiles" | awk '{print $1}') -eq 0 ] ; then
  362.         parse_profiles load
  363.     else
  364.         aa_log_skipped_msg "Loading AppArmor profiles - AppArmor already loaded with profiles."
  365.     fi
  366. }
  367.  
  368. remove_profiles() {
  369.  
  370.     # removing profiles as we directly read from subdomainfs
  371.     # doesn't work, since we are removing entries which screws up
  372.     # our position.  Lets hope there are never enough profiles to
  373.     # overflow the variable
  374.     if ! is_apparmor_loaded ; then
  375.         aa_log_failure_msg "- failed, is AppArmor loaded?"
  376.         return 1
  377.     fi
  378.  
  379.     if [ ! -w "$SFS_MOUNTPOINT/.remove" ] ; then
  380.         aa_log_failure_msg "- failed, Do you have the correct privileges?"
  381.         return 1
  382.     fi
  383.  
  384.     if [ ! -x "${PARSER}" ] ; then
  385.         aa_log_failure_msg "- failed, unable to execute AppArmor parser"
  386.         return 1
  387.     fi
  388.  
  389.     retval=0
  390.     #the list of profiles isn't stable once we start adding or removing
  391.     #them so stor to tmp first
  392.     MODULE_PLIST=$(mktemp ${APPARMOR_TMPDIR}/tmp.XXXXXXXX)
  393.     sed -e "s/ (\(enforce\|complain\))$//" "$SFS_MOUNTPOINT/profiles" | sort >"$MODULE_PLIST"
  394.     cat "$MODULE_PLIST" | while read profile ; do
  395.         echo -n "$profile" > "$SFS_MOUNTPOINT/.remove"
  396.         rc=$?
  397.         if [ ${rc} -ne 0 ] ; then 
  398.             retval=${rc}
  399.         fi
  400.     done
  401.     rm "$MODULE_PLIST"
  402.     if [ ${retval} -eq 0 ] ; then
  403.         aa_log_success_msg
  404.     else
  405.         aa_log_failure_msg
  406.     fi    
  407.     return ${retval}
  408. }
  409.  
  410. apparmor_stop() {
  411.     echo -n "Unloading AppArmor profiles "
  412.     remove_profiles
  413.     return $?
  414. }
  415.  
  416. apparmor_kill() {
  417.     if ! is_apparmor_loaded ; then
  418.         aa_log_failure_msg "Killing AppArmor module - failed, AppArmor is not loaded."
  419.         return 1
  420.     fi
  421.  
  422.     unmount_subdomainfs
  423.     if is_apparmor_present apparmor ; then
  424.         MODULE=apparmor
  425.     elif is_apparmor_present subdomain ; then
  426.         MODULE=subdomain
  427.     else
  428.         aa_log_failure_msg "Killing AppArmor module - failed, AppArmor is builtin"
  429.         return 1
  430.     fi
  431.     aa_action "Unloading AppArmor modules" /sbin/modprobe -qr $MODULE
  432.     return $?
  433. }
  434.  
  435. __apparmor_restart() {
  436.     if [ ! -w "$SFS_MOUNTPOINT/.load" ] ; then
  437.         aa_log_failure_msg "Loading AppArmor profiles - failed, Do you have the correct privileges?"
  438.         return 4
  439.     fi
  440.  
  441.     configure_owlsm
  442.     parse_profiles reload
  443.     PNAMES_LIST=$(mktemp ${APPARMOR_TMPDIR}/tmp.XXXXXXXX)
  444.     profiles_names_list ${PNAMES_LIST}
  445.     MODULE_PLIST=$(mktemp ${APPARMOR_TMPDIR}/tmp.XXXXXXXX)
  446.     sed  -e "s/ (\(enforce\|complain\))$//" "$SFS_MOUNTPOINT/profiles" | sort >"$MODULE_PLIST"
  447.     sort "$PNAMES_LIST" | comm -2 -3 "$MODULE_PLIST" - | while read profile ; do
  448.         echo -n "$profile" > "$SFS_MOUNTPOINT/.remove"
  449.     done
  450.     rm "$MODULE_PLIST"
  451.     rm "$PNAMES_LIST"
  452.     return 0
  453. }
  454.  
  455. apparmor_restart() {
  456.     if ! is_apparmor_loaded ; then
  457.         apparmor_start
  458.         rc=$?
  459.         return $rc
  460.     fi
  461.  
  462.     __apparmor_restart
  463.     return $?
  464. }
  465.  
  466. apparmor_try_restart() {
  467.     if ! is_apparmor_loaded ; then
  468.         return 0
  469.     fi
  470.  
  471.     __apparmor_restart
  472.     return $?
  473. }
  474.  
  475. configure_owlsm () {
  476.     if [ "${SUBDOMAIN_ENABLE_OWLSM}" = "yes" -a -f ${SFS_MOUNTPOINT}/control/owlsm ] ; then
  477.         # Sigh, the "sh -c" is necessary for the SuSE aa_action
  478.         # and it can't be abstracted out as a seperate function, as
  479.         # that breaks under RedHat's action, which needs a
  480.         # binary to invoke.
  481.         aa_action "Enabling OWLSM extension" sh -c "echo -n \"1\" > \"${SFS_MOUNTPOINT}/control/owlsm\""
  482.     elif [ -f "${SFS_MOUNTPOINT}/control/owlsm" ] ; then
  483.         aa_action "Disabling OWLSM extension" sh -c "echo -n \"0\" > \"${SFS_MOUNTPOINT}/control/owlsm\""
  484.     fi
  485. }
  486.  
  487. apparmor_status () {
  488.     if test -x ${AA_STATUS} ; then
  489.         ${AA_STATUS} --verbose
  490.         return $?
  491.     fi
  492.     if test -x ${SD_STATUS} ; then
  493.         ${SD_STATUS} --verbose
  494.         return $?
  495.     fi
  496.     if ! is_apparmor_present apparmor subdomain ; then
  497.         echo "AppArmor is not loaded."
  498.         rc=1
  499.     else
  500.         echo "AppArmor is enabled,"
  501.         rc=0
  502.     fi
  503.     echo "Install the apparmor-utils package to receive more detailed"
  504.     echo "status information here (or examine ${SFS_MOUNTPOINT} directly)."
  505.  
  506.     return $rc
  507. }
  508.